
#ifndef _VISUALIZACION_H

#define _VISUALIZACION_H

#include "Simulacion.h"
#include "Triangulo.h"
#include "Vector.h"
#include "Enumeraciones.h"

#if defined (__APPLE__)
#include <OpenGL/gl.h>			
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#include <GL/gl.h>			
#include <GL/glu.h>
#include <GL/glut.h>	
#endif

class Visualizacion
{
public:
    //Constructor
    Visualizacion();

    //Propiedades
    void set_TipoVisualizacion(TipoVisualizacion Tipovis){enmtipovisualizacion = Tipovis;}
    TipoVisualizacion get_TipoVisualizacion(){return enmtipovisualizacion;}

	void set_TipoSesion(TipoSesion TipoSes){enmTipoSesion = TipoSes;}
	
    void set_Simulacion(Simulacion& objSim){objSimulacion = objSim;}
	
    void set_PosOrganoX(const float &posOrgX){fPosXOrg = posOrgX;}
    void set_PosOrganoY(const float &posOrgY){fPosYOrg = posOrgY;}
    void set_PosOrganoZ(const float &posOrgZ){fPosZOrg = posOrgZ;}
    void set_RotOrganoX(const float &rotOrgX){fRotXOrg = rotOrgX;}
    void set_RotOrganoY(const float &rotOrgY){fRotYOrg = rotOrgY;}
    void set_RotOrganoZ(const float &rotOrgZ){fRotZOrg = rotOrgZ;}

	void set_NumeroCubos(int NroCubos){intNroCubos = NroCubos;}

    void set_IDTriangColisionado1(const int &id){intIDTriangColisionado1 = id;}
    int get_IDTriangColisionado1(){return intIDTriangColisionado1;}
    void set_IDTriangColisionado2(const int &id){intIDTriangColisionado2 = id;}
    int get_IDTriangColisionado2(){return intIDTriangColisionado2;}

	void set_IDTriangColisionadoCubo1(const int &id){intIDTriangColisionadoCubo1 = id;}
    int get_IDTriangColisionadoCubo1(){return intIDTriangColisionadoCubo1;}
    void set_IDTriangColisionadoCubo2(const int &id){intIDTriangColisionadoCubo2 = id;}
    int get_IDTriangColisionadoCubo2(){return intIDTriangColisionadoCubo2;}

	//Cubos de la sesion transportar cubos
	void set_MatAmbCubo(const Vector4f &material){MatAmbCubo = material;}
    void set_MatDifCubo(const Vector4f &material){MatDifCubo = material;}
    void set_MatSpcCubo(const Vector4f &material){MatSpcCubo = material;}
    void set_MatShnCubo(const float &material){MatShnCubo = material;}

	//Cubos de la sesion organizar cubos
	void set_vMatAmbCubo(const Vector4f &material, int i){vMatAmbCubo[i] = material;}
	void set_vMatDifCubo(const Vector4f &material, int i){vMatDifCubo[i] = material;}
	void set_vMatSpcCubo(const Vector4f &material, int i){vMatSpcCubo[i] = material;}
	void set_vMatShnCubo(const float material, int i){vMatShnCubo[i] = material;}

    void set_MatAmbOrgano(const Vector4f &material){MatAmbOrg = material;}
    void set_MatDifOrgano(const Vector4f &material){MatDifOrg = material;}
    void set_MatSpcOrgano(const Vector4f &material){MatSpcOrg = material;}
    void set_MatShnOrgano(const float &material){MatShnOrg = material;}
	
    void set_PosInstrumento1X(const float &posIns1X){fPosXInst1 = posIns1X;}
    void set_PosInstrumento1Y(const float &posIns1Y){fPosYInst1 = posIns1Y;}
    void set_PosInstrumento1Z(const float &posIns1Z){fPosZInst1 = posIns1Z;}
    void set_RotInstrumento1X(const float &rotIns1X){fRotXInst1 = rotIns1X;}
    void set_RotInstrumento1Y(const float &rotIns1Y){fRotYInst1 = rotIns1Y;}
    void set_RotInstrumento1Z(const float &rotIns1Z){fRotZInst1 = rotIns1Z;}
    void set_NumeroMallasInst1(const int &Mallas){intNroMallasInts1 = Mallas;}
    void set_MatAmbInst1(const Vector4f &material){MatAmbInst1 = material;}
    void set_MatDifInst1(const Vector4f &material){MatDifInst1 = material;}
    void set_MatSpcInst1(const Vector4f &material){MatSpcInst1 = material;}
    void set_MatShnInst1(const float &material){MatShnInst1 = material;}
	
    void set_PosInstrumento2X(const float &posIns2X){fPosXInst2 = posIns2X;}
    void set_PosInstrumento2Y(const float &posIns2Y){fPosYInst2 = posIns2Y;}
    void set_PosInstrumento2Z(const float &posIns2Z){fPosZInst2 = posIns2Z;}
    void set_RotInstrumento2X(const float &rotIns2X){fRotXInst2 = rotIns2X;}
    void set_RotInstrumento2Y(const float &rotIns2Y){fRotYInst2 = rotIns2Y;}
    void set_RotInstrumento2Z(const float &rotIns2Z){fRotZInst2 = rotIns2Z;}
    void set_NumeroMallasInst2(const int &Mallas){intNroMallasInts2 = Mallas;}
    void set_MatAmbInst2(const Vector4f &material){MatAmbInst2 = material;}
    void set_MatDifInst2(const Vector4f &material){MatDifInst2 = material;}
    void set_MatSpcInst2(const Vector4f &material){MatSpcInst2 = material;}
    void set_MatShnInst2(const float &material){MatShnInst2 = material;}

    //Metodos
    void Incializar();

	inline void DisplayCubo(int i)
	{
		//Aplica las traslaciones
		glTranslatef(objSimulacion.getOneCubo(i).get_PosX(), objSimulacion.getOneCubo(i).get_PosY(), 
			objSimulacion.getOneCubo(i).get_PosZ());
		//Aplica las rotaciones
		glRotatef(objSimulacion.getOneCubo(i).get_RotX(),1.0f, 0.0f, 0.0f);
		glRotatef(objSimulacion.getOneCubo(i).get_RotY(), 0.0f, 1.0f, 0.0f);
		glRotatef(objSimulacion.getOneCubo(i).get_RotZ(), 0.0f, 0.0f, 1.0f);
	
		if(enmtipovisualizacion == DIBUJAR_LINEAS){
			vector <Triangulo> temp = objSimulacion.getOneCubo(i).getSupTriang().get_Triangulos();
			Triangulo &t = temp[0];
			Vertice* prim;
			Vertice* seg;
			Vertice* ter;

			glDisable(GL_LIGHT1);								// Desabilita la luz 1
			glDisable(GL_LIGHTING);								// Desabilita la iluminacion

			for(unsigned int loop=0;loop<intNroTriangsCubo;loop++){
				t = temp[loop];

				prim = t.getVertice1();
				seg = t.getVertice2();
				ter = t.getVertice3();
				glBegin(GL_LINE_LOOP); 
				glVertex3f(prim->getX(), prim->getY(),prim->getZ());
				glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
				glVertex3f(ter->getX(), ter->getY(), ter->getZ());
				glEnd();
			}

			//Visualizando triangulo colisionado 1
			glColor3f(0.0f, 1.0f, 0.0f);
			t = temp[intIDTriangColisionadoCubo1];
			
			prim = t.getVertice1();
			seg = t.getVertice2();
			ter = t.getVertice3();
			glBegin(GL_LINE_LOOP); 
			glVertex3f(prim->getX(), prim->getY(),prim->getZ());
			glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
			glVertex3f(ter->getX(), ter->getY(), ter->getZ());
			glEnd();
			glColor3f(1.0f,0.0f,0.0f);

			//Visualizando triangulo colisionado 2
			glColor3f(1.0f, 1.0f, 0.0f);
			t = temp[intIDTriangColisionadoCubo2];
			
			prim = t.getVertice1();
			seg = t.getVertice2();
			ter = t.getVertice3();
			glBegin(GL_LINE_LOOP); 
			glVertex3f(prim->getX(), prim->getY(),prim->getZ());
			glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
			glVertex3f(ter->getX(), ter->getY(), ter->getZ());
			glEnd();
			glColor3f(1.0f,0.0f,0.0f);
		}
		else if(enmtipovisualizacion == DIBUJAR_PUNTOS){
			vector<Vertice*> temp = objSimulacion.getOneCubo(i).getSupTriang().get_Vertices();
			Vertice* prim;
			glPointSize(1.0f);
			glDisable(GL_LIGHT1);								// Desabilita la luz 1
			glDisable(GL_LIGHTING);								// Desabilita la iluminacion
	        
			for(unsigned int loop=0;loop<intNroVerticesCubo;loop++){
				prim = temp[loop];
				glBegin(GL_POINTS);
				glVertex3f(prim->getX(), prim->getY(),prim->getZ());
				glEnd();
			}

		}
		else if(enmtipovisualizacion == DIBUJAR_CONTORNO_FLAT){
			glEnable(GL_LIGHT1);								// Habilita la luz 1
			glEnable(GL_LIGHTING);								// Habilita la iluminacion

			if(enmTipoSesion == TRANSPORTAR_CUBOS)
			{
				float temp1[4] = {(float)MatAmbCubo.getValor(1),(float)MatAmbCubo.getValor(2),
								(float)MatAmbCubo.getValor(3),(float)MatAmbCubo.getValor(4)};
				float temp2[4] = {(float)MatDifCubo.getValor(1),(float)MatDifCubo.getValor(2),
								(float)MatDifCubo.getValor(3),(float)MatDifCubo.getValor(4)};
				float temp3[4] = {(float)MatSpcCubo.getValor(1),(float)MatSpcCubo.getValor(2),
								(float)MatSpcCubo.getValor(3),(float)MatSpcCubo.getValor(4)};

				glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
				//glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnCubo);		// Configura brillo del material
			}
			else if(enmTipoSesion == ORDENAR_CUBOS)
			{
				float temp1[4] = {(float)vMatAmbCubo[i].getValor(1),(float)vMatAmbCubo[i].getValor(2),
								(float)vMatAmbCubo[i].getValor(3),(float)vMatAmbCubo[i].getValor(4)};
				float temp2[4] = {(float)vMatDifCubo[i].getValor(1),(float)vMatDifCubo[i].getValor(2),
								(float)vMatDifCubo[i].getValor(3),(float)vMatDifCubo[i].getValor(4)};
				float temp3[4] = {(float)vMatSpcCubo[i].getValor(1),(float)vMatSpcCubo[i].getValor(2),
								(float)vMatSpcCubo[i].getValor(3),(float)vMatSpcCubo[i].getValor(4)};

				glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
				glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, vMatShnCubo[i]);		// Configura brillo del material
			}

			vector <Triangulo> temp = objSimulacion.getOneCubo(i).getSupTriang().get_Triangulos();
			Triangulo &t = temp[0];
			Vertice* prim;
			Vertice* seg;
			Vertice* ter;
			for(unsigned int loop=0;loop<intNroTriangsCubo;loop++){
				t = temp[loop];
				prim = t.getVertice1();
				seg = t.getVertice2();
				ter = t.getVertice3();

				glBegin(GL_TRIANGLES); 
				//glNormal3f(t.getNormal1().getUnitX(),t.getNormal1().getUnitY(),t.getNormal1().getUnitZ());
				glNormal3f(t.getNormal2().getUnitX(),t.getNormal2().getUnitY(),t.getNormal2().getUnitZ());
				glVertex3f(prim->getX(), prim->getY(),prim->getZ());
				glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
				glVertex3f(ter->getX(), ter->getY(), ter->getZ());
				glEnd();

			}
		}
		else if(enmtipovisualizacion == DIBUJAR_CONTORNO_SMOOTH) {

			glEnable(GL_LIGHT1);								// Habilita la luz 1
			glEnable(GL_LIGHTING);								// Habilita la iluminacion
			
			if(enmTipoSesion == TRANSPORTAR_CUBOS)
			{
				float temp1[4] = {(float)MatAmbCubo.getValor(1),(float)MatAmbCubo.getValor(2),
								(float)MatAmbCubo.getValor(3),(float)MatAmbCubo.getValor(4)};
				float temp2[4] = {(float)MatDifCubo.getValor(1),(float)MatDifCubo.getValor(2),
								(float)MatDifCubo.getValor(3),(float)MatDifCubo.getValor(4)};
				float temp3[4] = {(float)MatSpcCubo.getValor(1),(float)MatSpcCubo.getValor(2),
								(float)MatSpcCubo.getValor(3),(float)MatSpcCubo.getValor(4)};

				glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
				glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnOrg);		// Configura brillo del material
			}
			else if(enmTipoSesion == ORDENAR_CUBOS)
			{
				float temp1[4] = {(float)vMatAmbCubo[i].getValor(1),(float)vMatAmbCubo[i].getValor(2),
								(float)vMatAmbCubo[i].getValor(3),(float)vMatAmbCubo[i].getValor(4)};
				float temp2[4] = {(float)vMatDifCubo[i].getValor(1),(float)vMatDifCubo[i].getValor(2),
								(float)vMatDifCubo[i].getValor(3),(float)vMatDifCubo[i].getValor(4)};
				float temp3[4] = {(float)vMatSpcCubo[i].getValor(1),(float)vMatSpcCubo[i].getValor(2),
								(float)vMatSpcCubo[i].getValor(3),(float)vMatSpcCubo[i].getValor(4)};

				glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
				glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, vMatShnCubo[i]);		// Configura brillo del material
			}

			vector <Triangulo> temp = objSimulacion.getOneCubo(i).getSupTriang().get_Triangulos();
			Triangulo &t = temp[0];
			Vertice* prim;
			Vertice* seg;
			Vertice* ter;
			for(unsigned int loop=0;loop<intNroTriangsCubo;loop++){
				t = temp[loop];
				prim = t.getVertice1();
				seg = t.getVertice2();
				ter = t.getVertice3();

				glBegin(GL_TRIANGLES);
				glNormal3f(prim->getNormalVertice().getUnitX(),prim->getNormalVertice().getUnitY(),
						prim->getNormalVertice().getUnitZ());
				glVertex3f(prim->getX(), prim->getY(),prim->getZ());
				glNormal3f(seg->getNormalVertice().getUnitX(),seg->getNormalVertice().getUnitY(),
						seg->getNormalVertice().getUnitZ());
				glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
				glNormal3f(ter->getNormalVertice().getUnitX(),ter->getNormalVertice().getUnitY(),
						ter->getNormalVertice().getUnitZ());
				glVertex3f(ter->getX(), ter->getY(), ter->getZ());
				glEnd();

				//cout << t.getNormal().getUnitX() << " " << t.getNormal().getUnitY() << " " << 
				//t.getNormal().getUnitZ() <<  endl;
			}
		}
    }
        
    inline void DisplayOrgano(){
        //Aplica las traslaciones
        glTranslatef(fPosXOrg, fPosYOrg, fPosZOrg);
        //Aplica las rotaciones
        glRotatef(fRotXOrg, 1.0f, 0.0f, 0.0f);
        glRotatef(fRotYOrg, 0.0f, 1.0f, 0.0f);
        glRotatef(fRotZOrg, 0.0f, 0.0f, 1.0f);
	
        if(enmtipovisualizacion == DIBUJAR_LINEAS){
            vector <Triangulo> temp = objSimulacion.getOrgano().getSupTriang().get_Triangulos();
            Triangulo &t = temp[0];
            Vertice* prim;
            Vertice* seg;
            Vertice* ter;

            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion

            for(unsigned int loop=0;loop<intNroTriangsOrg;loop++){
                t = temp[loop];

                prim = t.getVertice1();
                seg = t.getVertice2();
                ter = t.getVertice3();
                glBegin(GL_LINE_LOOP); 
                glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
                glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                glEnd();
            }

			//Visualizando triangulo colisionado 1
            glColor3f(0.0f, 1.0f, 0.0f);
            t = temp[intIDTriangColisionado1];
			
            prim = t.getVertice1();
            seg = t.getVertice2();
            ter = t.getVertice3();
            glBegin(GL_LINE_LOOP); 
            glVertex3f(prim->getX(), prim->getY(),prim->getZ());
            glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
            glVertex3f(ter->getX(), ter->getY(), ter->getZ());
            glEnd();
            glColor3f(1.0f,0.0f,0.0f);

			//Visualizando triangulo colisionado 2
			glColor3f(1.0f, 1.0f, 0.0f);
            t = temp[intIDTriangColisionado2];
			
            prim = t.getVertice1();
            seg = t.getVertice2();
            ter = t.getVertice3();
            glBegin(GL_LINE_LOOP); 
            glVertex3f(prim->getX(), prim->getY(),prim->getZ());
            glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
            glVertex3f(ter->getX(), ter->getY(), ter->getZ());
            glEnd();
            glColor3f(1.0f,0.0f,0.0f);
        }
        else if(enmtipovisualizacion == DIBUJAR_PUNTOS){
            vector<Vertice*> temp = objSimulacion.getOrgano().getSupTriang().get_Vertices();
            Vertice* prim;
            glPointSize(1.0f);
            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion
            
            for(unsigned int loop=0;loop<intNroVerticesOrg;loop++){
                prim = temp[loop];
                glBegin(GL_POINTS);
                glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                glEnd();
            }

        }
        else if(enmtipovisualizacion == DIBUJAR_CONTORNO_FLAT){
            float temp1[4] = {(float)MatAmbOrg.getValor(1),(float)MatAmbOrg.getValor(2),
                              (float)MatAmbOrg.getValor(3),(float)MatAmbOrg.getValor(4)};
            float temp2[4] = {(float)MatDifOrg.getValor(1),(float)MatDifOrg.getValor(2),
                              (float)MatDifOrg.getValor(3),(float)MatDifOrg.getValor(4)};
            float temp3[4] = {(float)MatSpcOrg.getValor(1),(float)MatSpcOrg.getValor(2),
                              (float)MatSpcOrg.getValor(3),(float)MatSpcOrg.getValor(4)};

            //cout << objSimulacion.getOrgano().getMass_Spring_Model().getNroNodosModificados() << endl;

            if(objSimulacion.getOrgano().getMass_Spring_Model().getNroNodosModificados()!=0)
            {
                RecalcularNormales();
            }

            glEnable(GL_LIGHT1);								// Habilita la luz 1
            glEnable(GL_LIGHTING);								// Habilita la iluminacion

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
			glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnOrg);		// Configura brillo del material

            vector <Triangulo> temp = objSimulacion.getOrgano().getSupTriang().get_Triangulos();
            Triangulo &t = temp[0];
            Vertice* prim;
            Vertice* seg;
            Vertice* ter;
            for(unsigned int loop=0;loop<intNroTriangsOrg;loop++){
                t = temp[loop];
                prim = t.getVertice1();
                seg = t.getVertice2();
                ter = t.getVertice3();

                glBegin(GL_TRIANGLES); 
                glNormal3f(t.getNormal2().getUnitX(),t.getNormal2().getUnitY(),t.getNormal2().getUnitZ());
                glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
                glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                glEnd();

            }
        }
        else if(enmtipovisualizacion == DIBUJAR_CONTORNO_SMOOTH) {

            float temp1[4] = {(float)MatAmbOrg.getValor(1),(float)MatAmbOrg.getValor(2),
                              (float)MatAmbOrg.getValor(3),(float)MatAmbOrg.getValor(4)};
            float temp2[4] = {(float)MatDifOrg.getValor(1),(float)MatDifOrg.getValor(2),
                              (float)MatDifOrg.getValor(3),(float)MatDifOrg.getValor(4)};
            float temp3[4] = {(float)MatSpcOrg.getValor(1),(float)MatSpcOrg.getValor(2),
                              (float)MatSpcOrg.getValor(3),(float)MatSpcOrg.getValor(4)};

            //cout << objSimulacion.getOrgano().getMass_Spring_Model().getNroNodosModificados() << endl;

            if(objSimulacion.getOrgano().getMass_Spring_Model().getNroNodosModificados()!=0)
            {
                RecalcularNormales();
            }

            glEnable(GL_LIGHT1);								// Habilita la luz 1
            glEnable(GL_LIGHTING);								// Habilita la iluminacion

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
			glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnOrg);		// Configura brillo del material

            vector <Triangulo> temp = objSimulacion.getOrgano().getSupTriang().get_Triangulos();
            Triangulo &t = temp[0];
            Vertice* prim;
            Vertice* seg;
            Vertice* ter;
            for(unsigned int loop=0;loop<intNroTriangsOrg;loop++){
                t = temp[loop];
                prim = t.getVertice1();
                seg = t.getVertice2();
                ter = t.getVertice3();

                glBegin(GL_TRIANGLES);
                glNormal3f(prim->getNormalVertice().getUnitX(),prim->getNormalVertice().getUnitY(),
                           prim->getNormalVertice().getUnitZ());
                glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                glNormal3f(seg->getNormalVertice().getUnitX(),seg->getNormalVertice().getUnitY(),
                           seg->getNormalVertice().getUnitZ());
                glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
                glNormal3f(ter->getNormalVertice().getUnitX(),ter->getNormalVertice().getUnitY(),
                           ter->getNormalVertice().getUnitZ());
                glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                glEnd();

                //cout << t.getNormal().getUnitX() << " " << t.getNormal().getUnitY() << " " << 
                //t.getNormal().getUnitZ() <<  endl;
            }
        }
    }


        
    inline void DisplayInst1(){
        //Aplica las traslaciones
		glTranslatef(fPosXInst1, 250.0f, fPosZInst1);	
        //Aplica las rotaciones
		glRotatef(fRotXInst1, 1.0f, 0.0f, 0.0f);
        glRotatef(fRotYInst1, 0.0f, 1.0f, 0.0f);
		glRotatef(fRotZInst1, 0.0f, 0.0f, 1.0f);

		glTranslatef(0.0f,fPosYInst1,0.0f);

		//cout << -fPosYInst1 << endl;

        if(enmtipovisualizacion == DIBUJAR_LINEAS){
            vector <Triangulo> temp;
            Triangulo t;
            Vertice *prim;
            Vertice *seg;
            Vertice *ter;

            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion

            for(unsigned int i=0; i< intNroMallasInts1; i++){	
                intNroTriangsInts1 = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_NroTriangs();
                temp = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_Triangulos();
                
                for(unsigned int loop=0;loop<intNroTriangsInts1;loop++){
                    t = temp[loop];
                    prim = t.getVertice1();
                    seg = t.getVertice2();
                    ter = t.getVertice3();

                    //TEMPORAL
                   /* if(t.getID()==objSimulacion.getInstrumentoQco1().get_IDTriangCol() && i==6)
                    {
                        glColor3f(1.0f, 0.0f, 1.0f);
                    }
                    else
                    {
                        glColor3f(0.0f, 1.0f, 0.0f);
                    }*/

                    /*glBegin(GL_LINE_LOOP); 
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glVertex3f(seg->getX(), seg->getY(), seg->getZ());
                    glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                    glEnd();*/

					glBegin(GL_LINE_LOOP); 
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glVertex3f(seg->getX(), seg->getY(), seg->getZ());
                    glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                    glEnd();
                }
            }
        }else if(enmtipovisualizacion == DIBUJAR_PUNTOS){
            vector<Vertice*> temp;
            Vertice* prim;
            glPointSize(1.0f);
            
            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion

            for(unsigned int i=0;i<intNroMallasInts1;i++)
            {
                temp = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_Vertices();
                intNroVerticesInst1 = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_NroVertices();

                for(unsigned int loop=0;loop<intNroVerticesInst1;loop++){

                    prim = temp[loop];
	           
                    glBegin(GL_POINTS);
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glEnd();
                }
            }
        }else if(enmtipovisualizacion == DIBUJAR_CONTORNO_FLAT || enmtipovisualizacion == DIBUJAR_CONTORNO_SMOOTH){
            float temp1[4] = {(float)MatAmbInst1.getValor(1),(float)MatAmbInst1.getValor(2),
                              (float)MatAmbInst1.getValor(3),(float)MatAmbInst1.getValor(4)};
            float temp2[4] = {(float)MatDifInst1.getValor(1),(float)MatDifInst1.getValor(2),
                              (float)MatDifInst1.getValor(3),(float)MatDifInst1.getValor(4)};
            float temp3[4] = {(float)MatSpcInst1.getValor(1),(float)MatSpcInst1.getValor(2),
                              (float)MatSpcInst1.getValor(3),(float)MatSpcInst1.getValor(4)};

            glEnable(GL_LIGHT1);								// Habilita la luz 1
            glEnable(GL_LIGHTING);								// Habilita la iluminacion

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
			glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnInst1);		// Configura brillo del material

            vector <Triangulo> temp;
            Triangulo t;
            Vertice *prim;
            Vertice *seg;
            Vertice *ter;
            for(unsigned int i=0; i< intNroMallasInts1; i++){	
                intNroTriangsInts1 = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_NroTriangs();
                temp = objSimulacion.getInstrumentoQco1().getOneSupTriang(i).get_Triangulos();
                        
                for(unsigned int loop=0;loop<intNroTriangsInts1;loop++){
                    t = temp[loop];
                    prim = t.getVertice1();
                    seg = t.getVertice2();
                    ter = t.getVertice3();

                    glBegin(GL_TRIANGLES);
                    glNormal3f(t.getNormal1().getUnitX(),t.getNormal1().getUnitY(),t.getNormal1().getUnitZ());
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glVertex3f(seg->getX(), seg->getY(), seg->getZ());
                    glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                    glEnd();
                }
            }
        }
    }




        
    inline void DisplayInst2(){
       glTranslatef(fPosXInst2, 250.0f, fPosZInst2);	
        //Aplica las rotaciones
        glRotatef(fRotXInst2, 1.0f, 0.0f, 0.0f);
        glRotatef(fRotYInst2, 0.0f, 1.0f, 0.0f);
        glRotatef(fRotZInst2, 0.0f, 0.0f, 1.0f);	
        
		glTranslatef(0.0f,fPosYInst2,0.0f);

		if(enmtipovisualizacion == DIBUJAR_LINEAS){
            vector <Triangulo> temp;
            Triangulo t;
            Vertice *prim;
            Vertice *seg;
            Vertice *ter;

            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion

            for(unsigned int i=0; i< intNroMallasInts2; i++){	
                intNroTriangsInts2 = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_NroTriangs();
                temp = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_Triangulos();

                for(unsigned int loop=0;loop<intNroTriangsInts2;loop++){
                    t = temp[loop];
                    prim = t.getVertice1();
                    seg = t.getVertice2();
                    ter = t.getVertice3();

                    //TEMPORAL
                    if(t.getID()==objSimulacion.getInstrumentoQco1().get_IDTriangCol() && i==6)
                    {
                        glColor3f(1.0f, 0.5f, 0.0f);
                    }
                    else
                    {
                        glColor3f(0.0f, 0.0f, 1.0f);
                    }

                    glBegin(GL_LINE_LOOP); 
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
                    glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                    glEnd();
                }
            }
        }
        else if(enmtipovisualizacion == DIBUJAR_PUNTOS){
            vector<Vertice*> temp;
            Vertice* prim;
            glPointSize(1.0f);
            
            glDisable(GL_LIGHT1);								// Desabilita la luz 1
            glDisable(GL_LIGHTING);								// Desabilita la iluminacion

            for(unsigned int i=0;i<intNroMallasInts2;i++)
            {
                temp = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_Vertices();
                intNroVerticesInst2 = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_NroVertices();

                for(unsigned int loop=0;loop<intNroVerticesInst2;loop++){

                    prim = temp[loop];
	           
                    glBegin(GL_POINTS);
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glEnd();
                }
            }
        }else if(enmtipovisualizacion == DIBUJAR_CONTORNO_FLAT || DIBUJAR_CONTORNO_SMOOTH){
            float temp1[4] = {(float)MatAmbInst2.getValor(1),(float)MatAmbInst2.getValor(2),
                              (float)MatAmbInst2.getValor(3),(float)MatAmbInst2.getValor(4)};
            float temp2[4] = {(float)MatDifInst2.getValor(1),(float)MatDifInst2.getValor(2),
                              (float)MatDifInst2.getValor(3),(float)MatDifInst2.getValor(4)};
            float temp3[4] = {(float)MatSpcInst2.getValor(1),(float)MatSpcInst2.getValor(2),
                              (float)MatSpcInst2.getValor(3),(float)MatSpcInst2.getValor(4)};
            
            glEnable(GL_LIGHT1);								// Habilita la luz 1
            glEnable(GL_LIGHTING);								// Habilita la iluminacion

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, temp1);			// Configura material ambiental
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, temp2);			// Configura material difuso
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, temp3);		// Configura material especular
			glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShnInst2);		// Configura brillo del material

            vector <Triangulo> temp;
            Triangulo t;
            Vertice *prim;
            Vertice *seg;
            Vertice *ter;
            for(unsigned int i=0; i< intNroMallasInts2; i++){	
                intNroTriangsInts2 = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_NroTriangs();
                temp = objSimulacion.getInstrumentoQco2().getOneSupTriang(i).get_Triangulos();
	
                for(unsigned int loop=0;loop<intNroTriangsInts2;loop++){
                    t = temp[loop];
                    prim = t.getVertice1();
                    seg = t.getVertice2();
                    ter = t.getVertice3();

                    glBegin(GL_TRIANGLES); 
                    glNormal3f(t.getNormal1().getUnitX(),t.getNormal1().getUnitY(),t.getNormal1().getUnitZ());
                    glVertex3f(prim->getX(), prim->getY(),prim->getZ());
                    glVertex3f(seg->getX(), seg->getY(), seg->getZ());  
                    glVertex3f(ter->getX(), ter->getY(), ter->getZ());
                    glEnd();
                }
            }
        }
    }

private:
    //Atributos
    Simulacion objSimulacion;
    unsigned int intNroTriangsOrg;
    unsigned int intNroVerticesOrg;

	unsigned int intNroTriangsCubo;
	unsigned int intNroVerticesCubo;

    unsigned int intNroTriangsInts1;
    unsigned int intNroMallasInts1;
	unsigned int intNroVerticesInst1;
	
    unsigned int intNroTriangsInts2;
	unsigned int intNroVerticesInst2;
    unsigned int intNroMallasInts2;

    int intIDTriangColisionado1;
	int intIDTriangColisionado2;

	int intIDTriangColisionadoCubo1;
	int intIDTriangColisionadoCubo2;

    TipoVisualizacion enmtipovisualizacion;

	TipoSesion enmTipoSesion;

    float fPosXInst1, fPosYInst1, fPosZInst1;
    float fRotXInst1, fRotYInst1, fRotZInst1;

    float fPosXInst2, fPosYInst2, fPosZInst2;
    float fRotXInst2, fRotYInst2, fRotZInst2;

    float fPosXOrg, fPosYOrg, fPosZOrg;
    float fRotXOrg, fRotYOrg, fRotZOrg;

	int intNroCubos;

    //Materiales Organo
    Vector4f MatAmbOrg;
    Vector4f MatDifOrg;
    Vector4f MatSpcOrg;
    float MatShnOrg;

	 //Materiales Cubo Transportar Cubos
    Vector4f MatAmbCubo;
    Vector4f MatDifCubo;
    Vector4f MatSpcCubo;
    float MatShnCubo;

	//Materiales Organizar Cubo
	vector<Vector4f> vMatAmbCubo;
	vector<Vector4f> vMatDifCubo;
	vector<Vector4f> vMatSpcCubo;
	vector<float> vMatShnCubo;

    //Materiales Instrumento 1
    Vector4f MatAmbInst1;
    Vector4f MatDifInst1;
	Vector4f MatSpcInst1;
    float MatShnInst1;

    //Materiales Instrumento 2
    Vector4f MatAmbInst2;
    Vector4f MatDifInst2;
	Vector4f MatSpcInst2;
    float MatShnInst2;

public:
    void RecalcularNormales();
	void CastShadow(int nro, float *lp);
};


#endif
